package com.zws.cucumber.plugin;

import com.zws.cucumber.util.colorfullog.ZwsColorfulLogger;
import io.cucumber.plugin.EventListener;
import io.cucumber.plugin.event.EventPublisher;
import org.slf4j.Logger;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class ZwsPlugins implements EventListener {

    private static final Logger logger = ZwsColorfulLogger.of(ZwsPlugins.class);

    private static final List<ZwsPlugin> pluginList = new ArrayList<>();

    static {

        try {
            Class<?> zwsProcedurePluginImpl = Class.forName("com.zws.cucumber.plugin.procedure.ZwsProcedurePluginImpl");
            registerPlugin((ZwsPlugin) zwsProcedurePluginImpl.getDeclaredConstructor().newInstance());
            logger.info("Registered ZwsProcedurePluginImpl");
        } catch (ClassNotFoundException | InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException e) {
            logger.error("Missing com.zws.cucumber.plugins.procedure.ZwsProcedurePluginImpl", e);
        }

        try {
            Class<?> zwsSnapshotPluginImpl = Class.forName("com.zws.cucumber.plugin.snapshot.ZwsSnapshotPluginImpl");
            registerPlugin((ZwsPlugin) zwsSnapshotPluginImpl.getDeclaredConstructor().newInstance());
            logger.info("Registered ZwsSnapshotPluginImpl");
        } catch (ClassNotFoundException | InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException e) {
            logger.error("Missing com.zws.cucumber.plugins.snapshot.ZwsSnapshotPluginImpl", e);
        }
    }

    public static void registerPlugin(ZwsPlugin plugin) {
        logger.info("register plugin, name: {}, priority: {}", plugin.getName(), plugin.getPriority());
        pluginList.add(plugin);
        pluginList.sort(Comparator.comparingInt(ZwsPlugin::getPriority));
    }

    @Override
    public void setEventPublisher(EventPublisher eventPublisher) {
        ZwsPluginChain chain = new ZwsPluginChainDefaultImpl(pluginList);
        chain.invokeNext(eventPublisher);
    }
}
